package com.jmz.apt.api.Utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jmz.apt.api.exception.BusinessException;
import com.jmz.apt.api.message.request.Condition;
import com.jmz.apt.api.message.request.Data;
import com.jmz.apt.api.message.request.RequestMessageTemplate;
import com.jmz.apt.api.message.response.ResponseMessageTemplate;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.springframework.data.repository.init.ResourceReader.Type.JSON;

/**
 * Created by fanglexue on 2019/11/4.
 */
@Component
public class ValidatorBizUtil {
    /**
     * 日志
     */
    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 校验文件路径常量
     */
    public static final String CHECK_FILE_PATH = "check/";

    /**
     * 不检查
     */
    public static final String NO_CHECK = "NO_CHECK";

    /**
     * 获取系统配置的出错返回模式，默认快速返回，可以配置出错即返回或全部校验完毕统一返回
     */
    @Value("${jmz.validator.error-quick-back:true}")
    private boolean quickBack;

    /**
     * 检查规则
     */
    private static Map<String, JSONArray> checkMap = new HashMap<>();

    /**
     * 检测请求体中的条件
     *
     * @param checkRuleFile 规则检查文件
     * @return
     */
    public String checkCondition(List<Condition> conditions, String checkRuleFile) {
        StringBuilder resMessage = new StringBuilder();

        JSONArray jobj = JSONObject.parseArray(com.alibaba.fastjson.JSON.toJSONString(conditions));

        return checkJsonCondition(resMessage, checkRuleFile, jobj);

    }

    /**
     * 检查请求体中的数据的格式
     *
     * @param rmt
     * @param checkRuleFiles 支持 dataset名称:检查规则文件名称 模式来动态设定dataset集合的对应的检查规则，如果不用:来指定，则按dataset的顺序使用检查规则文件进行检查
     * @return
     * @throws Exception
     */
    public String checkRequestData(RequestMessageTemplate rmt, String... checkRuleFiles) {
        StringBuilder resMessage = new StringBuilder();

        List datas = rmt.getDataSet();

        //数据集检查规则需要与传入的datas的个数相同，无需检查的数据集使用ValidatorBizUtil.NO_CHECK标识
        if (datas.size() != checkRuleFiles.length) {
            throw new BusinessException("数据节点的个数与检查规则的个数不同，如果无需检查，请设置相应的检查规则为ValidatorBizUtil.NO_CHECK");
        }

        //for (int i=0; i <datas.size(); i++) {
        //com.jmz.common.message.request.Data data = (com.jmz.common.message.request.Data)datas.get(i);
        //List<Object> rows = data.getRow();
        for (int i = 0; i < checkRuleFiles.length; i++) {

            if (checkRuleFiles[i] == null) {
                throw new BusinessException(MessageFormat.format("未找到检查规则文件{0}", null));
            }

            String dsName = null; //记录集名称
            String ruleFile = null; //检查规则名称
            List<Object> rows = null;

            //如果传入的检查文件包含:则表示传入了datasetname和规则文件名
            if (checkRuleFiles[i].contains(":")) {
                //格式为 "datasetname:rulefilename"
                String[] rfs = checkRuleFiles[i].split(":");
                dsName = rfs[0];
                ruleFile = rfs[1];
                rows = rmt.getDataSetByKey(dsName);
            } else {
                Data data = (Data) datas.get(i);
                dsName = data.getName();
                ruleFile = checkRuleFiles[i];
                rows = data.getRow();
            }

            for (int j = 0; j < rows.size(); j++) {

                Object obj = rows.get(j);

                String rt = checkJson(ruleFile, obj, j, dsName);

                if (StringUtils.isNotEmpty(rt)) {
                    resMessage.append(rt);
                    resMessage.append("\r\n");
                }

                //如果是快速返回模式，并且已经有检查有问题的数据则返回
                if (quickBack && rt.length() > 0) {
                    return resMessage.toString();
                }
            }
        }


        return resMessage.toString();
    }

    /**
     * 检查响应体中的数据的格式
     *
     * @param rmt
     * @param checkRuleFiles
     * @return
     * @throws Exception
     */
    public String checkResponseData(ResponseMessageTemplate rmt, String... checkRuleFiles) {
        StringBuilder resMessage = new StringBuilder();

        List datas = rmt.getDataset();

        //数据集检查规则需要与传入的datas的个数相同，无需检查的数据集使用ValidatorBizUtil.NO_CHECK标识
        if (datas.size() != checkRuleFiles.length) {
            throw new BusinessException("数据节点的个数与检查规则的个数不同，如果无需检查，请设置相应的检查规则为ValidatorBizUtil.NO_CHECK");
        }

        for (int i = 0; i < datas.size(); i++) {
            com.jmz.apt.api.message.response.Data data = (com.jmz.apt.api.message.response.Data) datas.get(i);
            List<Object> rows = data.getRow();

            for (int j = 0; j < rows.size(); j++) {

                Object obj = rows.get(j);
                JSONObject jobj = JSONObject.parseObject(com.alibaba.fastjson.JSON.toJSONString(obj));

                String rt = checkJson(checkRuleFiles[i], jobj, j, data.getName());

                if (StringUtils.isNotEmpty(rt)) {
                    resMessage.append(rt);
                    resMessage.append("\r\n");
                }

                //如果是快速返回模式，并且已经有检查有问题的数据则返回
                if (quickBack && rt.length() > 0) {
                    return resMessage.toString();
                }
            }
        }

        return resMessage.toString();
    }


    /**
     * 默认使用中文提示返回
     *
     * @param checkFile
     * @param bean
     * @return
     * @throws Exception
     */
    public String checkJson(String checkFile, Object bean) {
        return checkJson(checkFile, bean, 0, "");
    }


    /**
     * @param checkFile 校验JSON文件名, 如果无需检查，则传入ValidatorBizUtil.NO_CHECK
     * @param bean      校验对象
     * @return java.lang.String
     * @throws Exception 异常消息
     * @author ChangK
     * @date 2019/3/30 21:40
     * @Description: {方法描述}
     */
    public String checkJson(String checkFile, Object bean, int rowNumber, String dataName) {

        StringBuilder resMsg = new StringBuilder();

        // 如果未指定检查规则文件，则直接返回，不进行检查
        if (StringUtils.isEmpty(checkFile)) {
            throw new BusinessException("请传入检查规则文件名");
        }

        if (ValidatorBizUtil.NO_CHECK.equals(checkFile)) {
            return resMsg.toString();
        }

        JSONObject itemJSONObj;
        if (bean instanceof HashMap) {
            itemJSONObj = JSONObject.parseObject(com.alibaba.fastjson.JSON.toJSONString(bean));
        } else if (bean instanceof JSONObject) {
            itemJSONObj = (JSONObject) bean;
        } else {
            throw new BusinessException("校验数据解析发生错误"); // "0","校验数据解析发生错误。"
        }


        // 如果传入的检查文件未包含check/路径信息，则加上该路径信息
        if (!checkFile.contains("check/")) {
            checkFile = ValidatorBizUtil.CHECK_FILE_PATH + checkFile + ".json";
        }

        JSONArray tableData;
        if (checkMap.containsKey(checkFile)) {
            tableData = checkMap.get(checkFile);
        } else {

            ClassPathResource classPathResource = new ClassPathResource(checkFile);
            String str = null;
            try {
                str = IOUtils.toString(new InputStreamReader(classPathResource.getInputStream(), "UTF-8"));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                logger.error(e.getMessage());
                // 如果未找到checkFile，则提示未找到
                throw new BusinessException(MessageFormat.format("未找到检查规则文件{0}", checkFile));
            }
            tableData = JSONArray.parseArray(str);

            //放入缓存
            checkMap.put(checkFile, tableData);
        }

        for (int i = 0; i < tableData.size(); i++) {

            Object chkField = tableData.get(i);

            String name = ((JSONObject) chkField).get("name").toString();
            Object required = ((JSONObject) chkField).get("required");
            Object type = ((JSONObject) chkField).get("type");
            Object length = ((JSONObject) chkField).get("length");
            Object dicEntity = ((JSONObject) chkField).get("dic_entity");
            Object description = ((JSONObject) chkField).get("description");
            Object range = ((JSONObject) chkField).get("range");
            String nameDesc = name;
            if (description != null && !"".equals(description.toString().trim())) {
                nameDesc = description.toString().trim();
            }

            // 获取字段内容
            Object val = null;

            // 获取字段内容
            val = itemJSONObj.get(name);

            // 必填校验
            if (required != null && "1".equals(required.toString())) {
                if (val == null || "".equals(val.toString().trim())) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("必须填写"); // 必须填写；
                    resMsg.append("\t" + MessageFormat.format("行号:{0}", rowNumber + "\t dataName:" + dataName + "\t "));

                    if (quickBack) {
                        return resMsg.toString();
                    } else {
                        continue;
                    }
                }
            }
            // 字段类型校验
            if (!checkType(resMsg, val, type, nameDesc, name)) {

                resMsg.append("\t" + MessageFormat.format("行号:{0}", rowNumber + "\t dataName:" + dataName + "\t "));

                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
            // 字段长度校验
            if (!checkLen(resMsg, val, length, nameDesc, name)) {
                resMsg.append("\t" + MessageFormat.format("行号:{0}", rowNumber + "\t dataName:" + dataName + "\t "));

                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
            // 字段字典值域校验
//            if (!checkDicEntity(resMsg, val, dicEntity, nameDesc, name)) {
//                resMsg.append("\t" + MessageFormat.format("validator_0", rowNumber + "\t dataName:" + dataName + "\t "));
//
//                if (quickBack) {
//                    return resMsg.toString();
//                } else {
//                    continue;
//                }
//            }
            // 字段范围校验
            if (!checkRange(resMsg, val, range, nameDesc, name)) {
                resMsg.append("\t" + MessageFormat.format("行号:{0}", rowNumber + "\t dataName:" + dataName + "\t "));

                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
        }
        // 返回错误内容
        return resMsg.toString();
    }


    /**
     * 检查condition节点
     *
     * @param resMsg
     * @param checkFile
     * @param bean
     * @return
     */
    public String checkJsonCondition(StringBuilder resMsg, String checkFile, JSONArray bean) {

        // 如果未指定检查规则文件，则直接返回，不进行检查
        if (StringUtils.isEmpty(checkFile)) {
            throw new BusinessException("请传入检查规则文件名");
        }

        // 如果传入的检查文件未包含check/路径信息，则加上该路径信息
        if (!checkFile.contains("check/")) {
            checkFile = ValidatorBizUtil.CHECK_FILE_PATH + checkFile + ".json";
        }

        JSONArray tableData;
        if (checkMap.containsKey(checkFile)) {
            tableData = checkMap.get(checkFile);
        } else {

            ClassPathResource classPathResource = new ClassPathResource(checkFile);
            String str = null;
            try {
                str = IOUtils.toString(new InputStreamReader(classPathResource.getInputStream(), "UTF-8"));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                logger.error(e.getMessage());
                // 如果未找到checkFile，则提示未找到
                throw new BusinessException(MessageFormat.format("未找到检查规则文件{0}", checkFile));
            }
            tableData = JSONArray.parseArray(str);

            // 放入缓存
            checkMap.put(checkFile, tableData);
        }

        for (int i = 0; i < tableData.size(); i++) {

            Object chkField = tableData.get(i);

            String name = ((JSONObject) chkField).get("name").toString();
            Object required = ((JSONObject) chkField).get("required");
            Object type = ((JSONObject) chkField).get("type");
            Object length = ((JSONObject) chkField).get("length");
            Object dicEntity = ((JSONObject) chkField).get("dic_entity");
            Object description = ((JSONObject) chkField).get("description_");
            Object range = ((JSONObject) chkField).get("range");
            String nameDesc = name;
            if (description != null && !"".equals(description.toString().trim())) {
                nameDesc = description.toString().trim();
            }

            // 获取条件值
            Object val = null;

            // 循环检查传入的条件集合中是否存在必须校验的条件值
            for (int k = 0; k < bean.size(); k++) {

                JSONObject itemJSONObj = (JSONObject) bean.get(k);

                // 判断当前检查规则中的要求的对象名称是否是当前condition节点，如果不是用下一个校验规则进行检验
                if (name.equals(itemJSONObj.get("name"))) {
                    val = itemJSONObj.get("value");
                    break;
                }
            }

            // 必填校验
            if (required != null && "1".equals(required.toString())) {

                if (val == null || "".equals(val.toString().trim())) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("必须填写"); // 必须填写；
                    resMsg.append("\t" + MessageFormat.format("行号:{0}", 0 + "\t conditionName:" + name + "\t "));
                    resMsg.append("\r\n");

                    if (quickBack) {
                        return resMsg.toString();
                    } else {
                        continue;
                    }
                }
            }

            // 字段类型校验
            if (!checkType(resMsg, val, type, nameDesc, name)) {

                resMsg.append("\t" + MessageFormat.format("行号:{0}", 0 + "\t conditionName:" + name + "\t "));
                resMsg.append("\r\n");
                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
            // 字段长度校验
            if (!checkLen(resMsg, val, length, nameDesc, name)) {
                resMsg.append("\t" + MessageFormat.format("行号:{0}", 0 + "\t conditionName:" + name + "\t "));
                resMsg.append("\r\n");
                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
//            // 字段字典值域校验
//            if (!checkDicEntity(resMsg, val, dicEntity, nameDesc, name)) {
//                resMsg.append("\t" + LangMapper.s(lang, "validator_0", 0 + "\t conditionName:" + name + "\t "));
//                resMsg.append("\r\n");
//                if (quickBack) {
//                    return resMsg.toString();
//                } else {
//                    continue;
//                }
//            }
            // 字段范围校验
            if (!checkRange(resMsg, val, range, nameDesc, name)) {
                resMsg.append("\t" + MessageFormat.format("行号:{0}", 0 + "\t conditionName:" + name + "\t "));
                resMsg.append("\r\n");
                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }

        }
        // 返回错误内容
        return resMsg.toString();
    }

    /**
     * @param resMsg   错误消息对象
     * @param val      校验字段值
     * @param type     字段类型
     * @param nameDesc 字段描述
     * @param name     字段名
     * @return boolean 校验结果（true：校验通过，false：校验不通过）
     * @author ChangK
     * @date 2019/3/31 11:36
     * @Description: 字段类型校验
     */
    private boolean checkType(StringBuilder resMsg, Object val, Object type, String nameDesc,
                              String name) {
        boolean res = true;
        // 类型校验
        if (val != null && type != null && !"".equals(type.toString())) {
            if ("int".equals(type.toString())) {
                try {
                    Integer.valueOf(val.toString());
                } catch (NumberFormatException e) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("不是int类型");  //不是int类型；
                    res = false;
                }
            } else if ("bigint".equals(type.toString())) {
                try {
                    Long.valueOf(val.toString());
                } catch (NumberFormatException e) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("不是bigint类型");  //不是bigint类型；
                    res = false;
                }
            } else if ("datetime".equals(type.toString())) {
                SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                boolean isOk = true;
                try {
                    if (val.toString().length() == 19) {
                        //设置包容性,为true时,比如"1992-12-32"则会变成"1993-1-1",这里为了检验,设为false
                        format1.setLenient(false);
                        format1.parse(val.toString());
                    } else {
                        throw new ParseException("不是指定日期格式{yyyy-MM-dd HH:mm:ss}", 0);
                    }
                } catch (ParseException e) {
                    isOk = false;
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("不是指定日期格式{yyyy-MM-dd HH:mm:ss}");  //不是日期类型
                }
                return isOk;
            } else if ("date".equals(type.toString())) {
                SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
                boolean isOk = true;
                try {
                    if (val.toString().length() == 10) {
                        //设置包容性,为true时,比如"1992-12-32"则会变成"1993-1-1",这里为了检验,设为false
                        format2.setLenient(false);
                        format2.parse(val.toString());
                    } else {
                        throw new ParseException("不是指定日期格式{yyyy-MM-dd}", 0);
                    }
                } catch (ParseException e) {
                    isOk = false;
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("不是指定日期格式{yyyy-MM-dd}");  //不是日期类型
                }
                return isOk;
            } else if ("time".equals(type.toString())) {
                SimpleDateFormat format3 = new SimpleDateFormat("HH:mm:ss");
                boolean isOk = true;
                try {
                    if (val.toString().length() == 8) {
                        //设置包容性,为true时,比如"1992-12-32"则会变成"1993-1-1",这里为了检验,设为false
                        format3.setLenient(false);
                        format3.parse(val.toString());
                    } else {
                        throw new ParseException("不是指定日期格式{HH:mm:ss}", 0);
                    }
                } catch (ParseException e) {
                    isOk = false;
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("不是指定日期格式{HH:mm:ss}");  //不是日期类型
                }
                return isOk;
            } else if ("bigdecimal".equals(type.toString())) {
                try {
                    Double.valueOf(val.toString());
                } catch (NumberFormatException e) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("不是浮点类型");  //不是浮点类型；
                    res = false;
                }
            }
        }
        return res;
    }

    /**
     * @param resMsg   错误消息对象
     * @param val      校验字段值
     * @param length   字段长度
     * @param nameDesc 字段描述
     * @param name     字段名
     * @return boolean 校验结果（true：校验通过，false：校验不通过）
     * @throws Exception 异常信息
     * @author ChangK
     * @date 2019/3/31 11:44
     * @Description: 校验字段长度
     */
    private boolean checkLen(StringBuilder resMsg, Object val, Object length, String nameDesc,
                             String name) {
        boolean res = true;
        if (val != null && length != null && !"".equals(length.toString())) {
            try {
                // 长度校验
                Integer len = Integer.valueOf(length.toString());
                if (val != null && val.toString().getBytes("utf-8").length > len) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")长度超过了");
                    resMsg.append(len);
                    resMsg.append("字节；");
                    res = false;
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                logger.error(ex.getMessage());
                res = false;
            }
        }
        return res;
    }


    /**
     * @param resMsg   错误消息对象
     * @param val      校验字段值
     * @param range    范围值（【,】分割）
     * @param nameDesc 字段描述
     * @param name     字段名
     * @author ChangK
     * @date 2019/3/31 11:44
     * @Description: 校验字段范围值
     */
    private boolean checkRange(StringBuilder resMsg, Object val, Object range, String nameDesc,
                               String name) {
        boolean res = true;
        if (val != null && range != null && !"".equals(range.toString().trim())) {
            // 指定范围校验
            if (!ArrayUtils.contains(range.toString().split(","), val.toString())) {
                resMsg.append(nameDesc);
                resMsg.append("(");
                resMsg.append(name);
                resMsg.append(")");
                resMsg.append("不在指定范围内");  //不在指定范围内；
                res = false;
            }
        }
        return res;
    }

    /**
     * 检查请求体中的数据的格式
     *
     * @param object
     * @param checkRuleFiles 支持 dataset名称:检查规则文件名称 模式来动态设定dataset集合的对应的检查规则，如果不用:来指定，则按dataset的顺序使用检查规则文件进行检查
     * @return
     * @throws Exception
     */
    public String checkHisRequestData(Object object, String checkRuleFiles) {
        StringBuilder resMessage = new StringBuilder();

        if (checkRuleFiles == null) {
            throw new BusinessException(MessageFormat.format("未找到检查规则文件{0}", null));
        }
        String ruleFile = checkRuleFiles; //检查规则名称
        String rt = checkJsonHis(ruleFile, object);
        if (StringUtils.isNotEmpty(rt)) {
            resMessage.append(rt);
            resMessage.append("\r\n");
        }
        //如果是快速返回模式，并且已经有检查有问题的数据则返回
        if (quickBack && rt.length() > 0) {
            return resMessage.toString();
        }
        return resMessage.toString();
    }

    public String checkJsonHis(String checkFile, Object bean) {

        StringBuilder resMsg = new StringBuilder();
        // 如果未指定检查规则文件，则直接返回，不进行检查
        if (StringUtils.isEmpty(checkFile)) {
            throw new BusinessException("请传入检查规则文件名");
        }
        if (ValidatorBizUtil.NO_CHECK.equals(checkFile)) {
            return resMsg.toString();
        }
        JSONObject itemJSONObj = JSONObject.parseObject(com.alibaba.fastjson.JSON.toJSONString(bean));

        // 如果传入的检查文件未包含check/路径信息，则加上该路径信息
        if (!checkFile.contains("check/")) {
            checkFile = ValidatorBizUtil.CHECK_FILE_PATH + checkFile + ".json";
        }
        JSONArray tableData;
        if (checkMap.containsKey(checkFile)) {
            tableData = checkMap.get(checkFile);
        } else {
            ClassPathResource classPathResource = new ClassPathResource(checkFile);
            String str = null;
            try {
                str = IOUtils.toString(new InputStreamReader(classPathResource.getInputStream(), "UTF-8"));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                logger.error(e.getMessage());
                // 如果未找到checkFile，则提示未找到
                throw new BusinessException(MessageFormat.format("未找到检查规则文件{0}", checkFile));
            }
            tableData = JSONArray.parseArray(str);
            //放入缓存
            checkMap.put(checkFile, tableData);
        }
        for (int i = 0; i < tableData.size(); i++) {

            Object chkField = tableData.get(i);
            String name = ((JSONObject) chkField).get("name").toString();
            Object required = ((JSONObject) chkField).get("required");
            Object type = ((JSONObject) chkField).get("type");
            Object length = ((JSONObject) chkField).get("length");
            Object description = ((JSONObject) chkField).get("description");
            Object range = ((JSONObject) chkField).get("range");
            String nameDesc = name;
            if (description != null && !"".equals(description.toString().trim())) {
                nameDesc = description.toString().trim();
            }
            // 获取字段内容
            Object val = null;
            // 获取字段内容
            val = itemJSONObj.get(name);
            // 必填校验
            if (required != null && "1".equals(required.toString())) {
                if (val == null || "".equals(val.toString().trim())) {
                    resMsg.append(nameDesc);
                    resMsg.append("(");
                    resMsg.append(name);
                    resMsg.append(")");
                    resMsg.append("必须填写"); // 必须填写；
                    if (quickBack) {
                        return resMsg.toString();
                    } else {
                        continue;
                    }
                }
            }
            // 字段类型校验
            if (!checkType(resMsg, val, type, nameDesc, name)) {
                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
            // 字段长度校验
            if (!checkLen(resMsg, val, length, nameDesc, name)) {
                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
            // 字段范围校验
            if (!checkRange(resMsg, val, range, nameDesc, name)) {
                if (quickBack) {
                    return resMsg.toString();
                } else {
                    continue;
                }
            }
        }
        // 返回错误内容
        return resMsg.toString();
    }
}
